package com.ocp.macro.service.impl;

import com.ocp.macro.annotation.AutowireUserToken;
import com.ocp.macro.entity.*;
import com.ocp.macro.enums.DataCode;
import com.ocp.macro.mapper.allocation.AllocationMapper;
import com.ocp.macro.service.AllocationService;
import com.ocp.macro.utils.GsonUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author lhd
 * @version 1.0
 * @date 2021/10/6 23:20
 * 定制调拨单
 */

@Service
@Transactional(rollbackFor = Exception.class)
public class AllocationServiceImpl implements AllocationService {

    @Resource
    private AllocationMapper allocationMapper;

    /**
     * 调拨定制单预加载页面信息
     * @param userInfoToken 获取运营信息
     * @return json
     */
    @Cacheable(cacheNames = "loading")
    @AutowireUserToken(name = "userInfoToken")
    @Override
    public String loadingInfo(UserInfoToken userInfoToken) {
        Map<String, Object> map = new HashMap<>();
        //运营id
        Integer userId = userInfoToken.getUserId();
        //经销商
        List<DealList> dealLists = allocationMapper.selectDealListById(userId);
        map.put("dealerInfos",dealLists);
        //调拨单号
        Date date = new Date();
        SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String alctNo = "DB"+simpleFormat.format(date);
        map.put("alctNo",alctNo);
        //抬头、创建人
        Operate operate = allocationMapper.selectOperate(userId);
        map.put("operate",operate);
        //机构列表
        List<Organization> organizations = allocationMapper.selectOrganizations();
        map.put("orgs",organizations);
        //创建时间
        Date createDate = new Date();
        SimpleDateFormat createFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        map.put("createDate",createFormat.format(createDate));
        //调拨类型
        map.put("alctTypes",allocationMapper.selectAllocationTypes());
        //发货方式
        map.put("delivers",allocationMapper.selectDelivers());
        map.put("code", DataCode.SUCCESS.getCode());
        map.put("message",DataCode.SUCCESS.getMessage());
        return GsonUtils.toJson(map);
    }

    /**
     * 调拨仓库信息
     * @param orgId 机构id
     * @return json 仓库
     */
    @Override
    public String deposInfo(Integer orgId) {
        Map<String, Object> map = new HashMap<>();
        map.put("data",allocationMapper.selectDepositoryByOrgId(orgId));
        map.put("code", DataCode.SUCCESS.getCode());
        map.put("message",DataCode.SUCCESS.getMessage());
        return GsonUtils.toJson(map);
    }

    /**
     * 送货地址信息
     * @param dealerListId  经销商id
     * @return 返回送货地址信息\关联备货订单编号json
     */
    @Override
    public String addressList(Integer dealerListId) {
        Map<String, Object> map = new HashMap<>();
        map.put("data",allocationMapper.selectAddressAccountById(dealerListId));
        map.put("isData",allocationMapper.selectStockId(dealerListId));
        map.put("code", DataCode.SUCCESS.getCode());
        map.put("message",DataCode.SUCCESS.getMessage());
        return GsonUtils.toJson(map);
    }

    /**
     * 送货地址信息详情
     * @param addrId 送货地址id
     * @return 返回送货地址详细信息json
     */
    @Override
    public String addressInfo(Integer addrId) {
        Map<String, Object> map = new HashMap<>();
        map.put("data",allocationMapper.selectAddressById(addrId));
        map.put("code", DataCode.SUCCESS.getCode());
        map.put("message",DataCode.SUCCESS.getMessage());
        return GsonUtils.toJson(map);
    }

    /**
     * 在仓库库位表中查询产品编号
     * @param deposNo
     * @return 产品编号
     */
    @Override
    public String deposProductNo(String deposNo) {
        Map<String, Object> map = new HashMap<>();
        map.put("data",allocationMapper.selectDeposPlaces(deposNo));
        map.put("code", DataCode.SUCCESS.getCode());
        map.put("message",DataCode.SUCCESS.getMessage());
        return GsonUtils.toJson(map);
    }

    /**
     *
     * 查看出库和入库的库位详细信息
     * @param proNo 产品编号
     * @param indeposNo 入仓库编号
     * @param outdeposNo 出仓库编号
     * @return 返回库位编码、库位名称、出库时的可发货库存等
     */
    @Override
    public String deposPlacesAll(String proNo, String indeposNo,String outdeposNo) {
        Map<String, Object> map = new HashMap<>();
        map.put("product",allocationMapper.productList(proNo));
        map.put("indepos",allocationMapper.selectDeposPlacesAll(proNo,indeposNo));
        map.put("outdepos",allocationMapper.selectDeposPlacesAll(proNo,outdeposNo));
        map.put("code", DataCode.SUCCESS.getCode());
        map.put("message",DataCode.SUCCESS.getMessage());
        return GsonUtils.toJson(map);
    }

    /**
     * 查询备货订单详细信息
     * @param stockNo 备货订单编号
     * @return 备货订单详细信息
     */
    @Override
    public String manyStocks(String stockNo) {
        Map<String, Object> map = new HashMap<>();
        map.put("data",allocationMapper.selectStocks(stockNo));
        map.put("code", DataCode.SUCCESS.getCode());
        map.put("message",DataCode.SUCCESS.getMessage());
        return GsonUtils.toJson(map);
    }

    /**
     * 生成调拨单
     * @param allocation  将上方调拨信息
     * @param alctProduct 下方的库位多条信息
     * @return 返回成功或者失败
     */
    @Override
    public String allocationCreate(Allocation allocation, List<AlctProduct> alctProduct) {
        Map<String, Object> map = new HashMap<>();
        //判读库位数量是否足够
        for (AlctProduct product : alctProduct) {
            Integer integer = allocationMapper.selectDepos(product.getOutPlaceNo());
            if(integer!=null&&product.getOutProNumber()>integer){
                throw new RuntimeException("库位产品数量不足");
            }
        }
        //更新库位值
        for (AlctProduct product : alctProduct) {

            Integer up1 = allocationMapper.updateDeposPlace(product.getOutPlaceNo(), allocationMapper.selectDepos(product.getOutPlaceNo())-product.getOutProNumber());
            Integer up2 = allocationMapper.updateDeposPlace(product.getInPlaceNo(),allocationMapper.selectDepos(product.getInPlaceNo())+product.getInDepsStock());
            if(up1<=0||up2<=0){
                throw new RuntimeException("库位产品数量更新失败");
            }
        }
        //生成调拨单
        Integer allocationId = allocationMapper.inAllocation(allocation);
        Integer alctProductNum = allocationMapper.insertAlctProduct(alctProduct);
        if(allocationId<=0||alctProductNum<=0){
            throw new RuntimeException("生成调拨单失败");
        }
        //生成关系
        ArrayList<Map<String, Object>> arrayList = new ArrayList<>();
        for (AlctProduct product : alctProduct) {
            Map<String, Object> hashMap = new HashMap<>();
            hashMap.put("alctNo",allocation.getAlctNo());
            hashMap.put("alctProId",product.getAlctpId());
            arrayList.add(hashMap);
        }
        Integer relNum = allocationMapper.insertAlctProductRel(arrayList);
        if(relNum<=0){
            throw new RuntimeException("生成调拨单失败");
        }
        map.put("code", DataCode.SUCCESS.getCode());
        map.put("message",DataCode.SUCCESS.getMessage());
        return GsonUtils.toJson(map);
    }

    @Override
    public String selectstockNo() {

        Map<String, Object> map = new HashMap<>();
        map.put("data",allocationMapper.selectstockNo());
        map.put("code", DataCode.SUCCESS.getCode());
        map.put("message",DataCode.SUCCESS.getMessage());
        return GsonUtils.toJson(map);
    }
}
